package mbp.core;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;

import mbp.base.EnumType;
import mbp.base.FeatureType;
import mbp.exceptions.InvalidFeatureNameException;
import mbp.exceptions.InvalidFeatureTypeException;
import mbp.exceptions.InvalidFeatureValueException;
import mbp.exceptions.ParseExpressionErrorException;

/**
 * Implementuje metody tworzenia obiektow z lsowowymi wartosciami.
 * @author wojtek
 *
 */
public class RandObjectBuilder 
{
	Random generator;
	public RandObjectBuilder()
	{
		generator = new Random();
	}
	
	/**
	 * Zwraca liste zasobow z losowo wygenerowanymi watrosciami cech, spelniajacymi podany warunek akceptowalnosci.
	 * @param rcv Obiekt klasy ResourceValidation - warunek akceptowalnosci
	 * @param rc Obiekt klasy Resource - Zasob wzorcowy, wykorzystywany do ustawienia parametrow generatora
	 * @param size Maksymalna ilosc wygenerowanych zasobow.
	 * @return Lista wygenerowanych zasobow
	 */
	public List<Resource> getResourceList(ResourceValidation rcv, Resource rc, int size)
	{
		List<Resource> rcList = new ArrayList<Resource>();
		String rcType = rc.getType().getResourceTypeName();
		if(rcType.compareTo(rcv.getType().getResourceTypeName())!=0)
		{
			System.out.println("Wrong type");
			return null;
		}		
		ResourceTypeBuilder rtb = new ResourceTypeBuilder("");
		
		// | key | par1 | par2 | value |
		Map<String, Object[]> randomVaues = new HashMap<String, Object[]>();
		
		HashMap<String, FeatureType> features = rc.getType().getFeaturesCollection();
		Iterator<String> it = features.keySet().iterator();
		while(it.hasNext())
		{
			String key = it.next();
			FeatureType fType = features.get(key);
			switch(fType)
			{
			case INT:
				//generator.nextInt(ipar1) + ipar2
				Integer vint;
				try {
					vint = (Integer) rc.getFeatureValue(key);
					int ipar1 = vint+1;
					//if(ipar1==0)ipar1 = 10;
					if(ipar1<0)ipar1*=-1;
					
					int ipar2 = -(ipar1/2) + vint;
					//if(vint<0) vint=vint*-1;
					//if(vint==0) vint=1;
					//int ipar1 = vint * 10;;
					//int ipar2 = vint;
					randomVaues.put( key, new Object[]{FeatureType.INT, new Integer(ipar1), new Integer(ipar2), null} );
				} catch (InvalidFeatureNameException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				break;
			case FLOAT:
				//generator.nextFloat() + fpar1 ) * fpar2
				Float vfloat;
				try {
					vfloat = (Float) rc.getFeatureValue(key);
					int foffset = (int) (vfloat * 2);
					randomVaues.put( key, new Object[]{FeatureType.FLOAT, new Integer(0), new Integer(foffset), null} );
				} catch (InvalidFeatureNameException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				break;
			case ENUM:
				EnumType et = rc.getType().getEnumTypes().get(key);
				int epar1 = et.getArray().length;
				randomVaues.put( key, new Object[]{FeatureType.ENUM, new Integer(epar1), new Integer(0), null} );
				break;
			}		
		}
		
		for(int i = 0; i<10000; i++)
		{
			Resource rcGen = new Resource(rtb.GetResourceType(rcType));
			Iterator<String> it2 = randomVaues.keySet().iterator();
			while(it2.hasNext())
			{
				String key = it2.next();
				//System.out.println(key + " " + randomVaues.get(key)[0] + " " + randomVaues.get(key)[1] + " " + randomVaues.get(key)[2]);
				FeatureType fType = (FeatureType) randomVaues.get(key)[0];
				int par1 = (Integer) randomVaues.get(key)[1];
				int par2 = (Integer) randomVaues.get(key)[2];
				switch(fType)
				{
				case INT:
					//generator.nextInt(ipar1) + ipar2
					if(key.compareTo("AMOUNT")==0)
					{
						randomVaues.get(key)[3] = new Integer(1);
					}
					else
					{
						randomVaues.get(key)[3] = generator.nextInt(par1) + par2;
					}
					
					break;
				case FLOAT:
					//generator.nextFloat() + fpar1 ) * fpar2
					randomVaues.get(key)[3] = ( generator.nextFloat() + par1 ) * par2;
					break;
				case ENUM:
					randomVaues.get(key)[3] = generator.nextInt(par1) + par2;
					break;
				}
			
				//System.out.println(key + " " + randomVaues.get(key)[0] + " " 
				//			+ randomVaues.get(key)[1] + " " + randomVaues.get(key)[2] + " " + randomVaues.get(key)[3]);
			
				try {
					rcGen.setFeatureValue(key, randomVaues.get(key)[3]);
				} catch (InvalidFeatureNameException e) {
					e.printStackTrace();
					return rcList;
				} catch (InvalidFeatureTypeException e) {
					e.printStackTrace();
					return rcList;
				} catch (InvalidFeatureValueException e) {
					e.printStackTrace();
					return rcList;
				}
			
			}
			rcGen.setValidDate(new Date());
			try {
				if(rcv.validateCondition(rcGen))
				{
					rcList.add(rcGen);
				}
			} catch (ParseExpressionErrorException e) {
				e.printStackTrace();
				return rcList;
			}
			
			//rcGen.printResourceInfo();
			if(rcList.size() == size)
			{
				break;
			}
		}
		
		return rcList;
	}

}
